package ${packageName}.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;



import com.google.common.collect.Lists;
import ${packageName}.cache.${className}Cache;
import ${packageName}.model.${className};
import top.suven.base.util.utilize.Page;
/**
 * @ClassName: ${className}Dao.java
 * @Description: ${description}的数据交互处理类
 * @author ${author}
 * @date   ${newdate}
 * @version V1.0.0
 * <p>
 * ----------------------------------------------------------------------------
 *  modifyer    modifyTime                 comment
 *
 * ----------------------------------------------------------------------------
 * </p>
 */
@Component
public class ${className}Dao extends ${className}Cache{

	@Autowired
	private ${dataSource} ${dataSourceLower};

	private final String SQL = "SELECT  ${selectSQL} ";

	/**
	 * 保存创建${className},并且保存到缓存中
	 * @param ${paramName}
	 */
      public ${className} save${className}(${className} ${paramName}){
        if(null == ${paramName})
            return  null;
		String sql = "INSERT INTO ${tableName} (${insertSQL}) "
		           + "VALUES(${insertVal}) ";
		${insertDbList}
	    long id = ${dataSourceLower}.insert(sql, "${id}", ${dbList});
	    if(id > 0){
	      ${paramName}.setId(id);
	      this.addCache(${paramName});//增加到缓存
	      return ${paramName};
	    }
	    return null;

      }


	/**
	 * 更新${paramName}信息,where条件为${paramName}Id,更新${paramName}
	 * @param ${paramName}
	 */
	public boolean update${className}(${className} ${paramName}){
		boolean flg = false ;
		if(null == ${paramName})
		   return  flg;
		String sql = "UPDATE ${tableName} SET ${updateSQL} "
		           + " WHERE ${id} = ? " ;

		${updateDbList}
		${updateWhereDbList}
	    flg = ${dataSourceLower}.update(sql,${dbList});
	    if(flg){
	    	this.addCache( ${paramName}); //更新到缓存;
	    }return flg;

	}

	/**
	 * 通过主键${paramName}Id删除${paramName}
	 *  @param ${paramName}Id
	 */
	public boolean  del${className}ById(long ${paramName}Id){
		if(${paramName}Id == 0)
	        return false;
		String sql = " DELETE FROM ${tableName} WHERE ${id} = ? ";
		this.delCache(${className}.class,${paramName}Id);//删除缓存
		return ${dataSourceLower}.update(sql,${paramName}Id);

	}


	/**
	 * 通过主键${paramName}删除${paramName}
	 *  @param ${paramName}
	 */
	public boolean  del${className}(${className} ${paramName}){
		if(null == ${paramName} || ${paramName}.getId() < 0)
	        return false;
		String sql = " DELETE FROM ${tableName} WHERE ${id} = ? ";
		this.delCache(${paramName});//删除缓存
		return ${dataSourceLower}.update(sql,${paramName}.getId());

	}

		/**
	 * 通过主键${paramName}Id查找${className}
	 * @param ${paramName}
	 */
	public ${className} get${className}(${className} ${paramName}){
		if(null == ${paramName} || ${paramName}.getId() < 0){
		   return  null;
		}
		long id =  ${paramName}.getId();
		${paramName} = this.findCache(${paramName} );//从缓存中查找
		if(null != ${paramName}){
			return ${paramName};
		}
		String sql = SQL
		              + " FROM ${tableName}  WHERE ${id} = ? ";

		${paramName} = ${dataSourceLower}.queryT(sql, ${paramName}Mapper, id);
		if(null == ${paramName}){
			return null;
		}
		this.addCache(${paramName});//增加到缓存;
		return  ${paramName};
	}

	/**
	 * 通过主键${paramName}Id查找${className}
	 * @param ${paramName}Id
	 */
	public ${className} get${className}ById(long ${paramName}Id){
		if(${paramName}Id <= 0)
		   return  null;
		${className} ${paramName} = this.findCacheById(${className}.class, ${paramName}Id );//从缓存中查找
		if(null != ${paramName}){
			return ${paramName};
		}
		String sql = SQL
		       + " FROM ${tableName}  WHERE ${id} = ? ";

		${paramName} = ${dataSourceLower}.queryT(sql, ${paramName}Mapper, ${paramName}Id);
		if(null == ${paramName}){
			return null;
		}
		this.addCache(${paramName});//增加到缓存;
		return  ${paramName};
	}


	/**
	 * 通过主键id集合批量查找${className} Collection<Long>
	 * @param colle
	 */
	public List<${className}>  get${className}ListByIdList(Collection<Long> colle){
		if(null == colle || colle.isEmpty()) {
		   return  null;
		}
		List<${className}> list = new ArrayList<>();
		//查找从缓存中没有查找到的${className}实现;
		Map<Long,${className}> map = this.findMapCache(${className}.class, colle );//从缓存中查找
		if(null != map ){
			 list = new ArrayList<>( map.values());
			 if( map.size() == colle.size()){
				 return list;
			 }
		}
		//查找从缓存中没有查找到的OpusInfo实现;
		if(null != map && !map.isEmpty()){
			Set<Long> mapkeys = map.keySet();
			colle.removeAll(mapkeys);//删除已查到的对象信息;
		}
		//删除之后为空集合,返回上面结果;
		if(colle.isEmpty()){
			return list;
		}

		String sql = SQL
		          + " FROM ${tableName}  WHERE ${id} IN ( ? ) ";

		if(colle.size() > ${dataSourceLower}.LISTS_PARTITON_SIZE){
			/*** 如果大于100条,则查用分页查询;返回结果值; */
			List<List<Long>> partition = Lists.partition(new ArrayList<>(colle),  ${dataSourceLower}.LISTS_PARTITON_SIZE);
			if(CollectionUtils.isNotEmpty(partition)){
				for(List<Long> colles : partition ){
					List<${className}>  dblist = ${dataSourceLower}.queryByInToList(sql, ${paramName}Mapper, colles);
					if(null != dblist && !dblist.isEmpty()){
						this.addCacheList(new ${className}(), dblist);
						list.addAll(dblist);
					}
				}
			}
		}else{

			List<${className}>  dblist = ${dataSourceLower}.queryByInToList(sql, ${paramName}Mapper, colle);
			if(null != dblist && !dblist.isEmpty()){
				this.addCacheList(new ${className}(), dblist);
				list.addAll(dblist);
			}
		}
		return  list;
	}

	/**
	 * 通过主键id集合批量查找${className}
	 * @param colle
	 */
	public Map<Long,${className}>  get${className}MapByIdList(Collection<Long> colle){
		int pageSize = 100;
		if(CollectionUtils.isEmpty(colle)){
			return new HashMap<Long, ${className}>();
		}
		Map<Long,${className}> map = this.findMapCache(${className}.class, colle);
		if(null != map && map.size() == colle.size() ){
			return map;
		}
		//查找从缓存中没有查找到的OpusInfo实现;
		if(null != map && !map.isEmpty()){
			Set<Long> mapkeys = map.keySet();
			colle.removeAll(mapkeys);//删除已查到的对象信息;
		}
		if(map == null){
			map = new HashMap<>();
		}
		List<${className}> list = new ArrayList<>();
		String sql = SQL
				+ " FROM ${tableName}  WHERE ${id} in ( ? )  ";
		/** 如果批量id 少于指定值时100条,直接查询**/
		if(colle.size() < pageSize && !colle.isEmpty()){
			list = ${dataSourceLower}.queryByInToList(sql, ${paramName}Mapper, colle);
		}else{
			/*** 如果大于100条,则查用分页查询;返回结果值; */
			List<List<Long>> partition = Lists.partition(new ArrayList<>(colle), pageSize);
			if(CollectionUtils.isNotEmpty(partition)){
				for(List<Long> ids : partition ){
					List<${className}> dblist = ${dataSourceLower}.queryByInToList(sql,${paramName}Mapper, ids);
					if(null != dblist && !dblist.isEmpty()){
						list.addAll(dblist);
					}
				}
			}

		}
		//从db中批量查找作品信息;
		if(CollectionUtils.isNotEmpty(list)){
			for (${className} ${paramName} : list) {
				map.put(${paramName}.getId(), ${paramName});
			}
			this.addCacheList(new ${className}(), list);

		}
		return map;
	}
	/**
	 * 通过分页Pager查找${className}
	 * @param page
	 */
	//@Deprecated
	public List<${className}>  get${className}ListByPage(Page page){
		if(null == page ) {
		   return  null;
		}
		//需要自己实现相关的分页和缓存业务
		String sql = SQL
		        + " FROM ${tableName}  WHERE 1 =1 limit ? , ?  ";

		String redisKey = this.getListForRedisKey("",${className}.class,
			page.getPageSize(), page.getStart());

		List<${className}> list  = this.findResultByCache(redisKey,${className}.class);//从缓存中查找
		if(null != list && !list.isEmpty()){
			return list;
		}
		list = ${dataSourceLower}.query(sql, ${paramName}Mapper ,page.getStart(),page.getPageSize());
		if(null != list && !list.isEmpty()){
			this.addResultToCache(redisKey,list);
		}
		return  list;

	}



	/**
	 * 查询使用映射对象Mapper
	 * @param ${paramName}Mapper
	 */
	private RowMapper<${className}> ${paramName}Mapper = new RowMapper<${className}>() {
		@Override
		public ${className} mapRow(ResultSet rs, int rowNum) throws SQLException {
			${className} vo = new ${className}();${resultVo}
			return vo;
		}
	};

}
